#ifndef __MY_SOCKET__H
#define __MY_SOCKET__H

#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<unistd.h>

#define MAX_LISTEN 5  //最大监听套接字个数

class TcpSocket{
private:
  int _sockfd;
public:
  TcpSocket():_sockfd(-1){}
  TcpSocket(int fd):_sockfd(fd) {}
  ~TcpSocket() 
  {
    // Close();
  }

  void SetFd(int fd) {_sockfd=fd;}
  int GetFd() { return _sockfd;}

  bool Socket(){
   //创建套接字
    _sockfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(_sockfd<0){
      perror("socket error!\n");
      return false;
    } 
    return true;
  }
  bool Bind(const std::string& ip,int port){ 
     struct sockaddr_in addr;
     addr.sin_family=AF_INET;
     addr.sin_port=htons(port);
     addr.sin_addr.s_addr=inet_addr(ip.c_str());
     socklen_t len=sizeof(addr);

     int ret=bind(_sockfd,(struct sockaddr*)&addr,len);
     if(ret<0){
       perror("bind error!\n");
       return false;
     } 
     return true;
  }
  bool Connect(const std::string& ip,int port){
     struct sockaddr_in addr;
     addr.sin_family=AF_INET;
     addr.sin_port=htons(port);
     addr.sin_addr.s_addr=inet_addr(ip.c_str());
     socklen_t len=sizeof(addr);

     int ret=connect(_sockfd,(struct sockaddr*)&addr,len);
     if(ret<0){
       perror("connect error!\n");
       return false;
     } 
     return true;
  } 
  bool Listen(int backlog=MAX_LISTEN){
      int ret= listen(_sockfd,backlog);
      if(ret<0){
        perror("listen error!\n");
        return false;
      }
      return true;
  }
  bool Accept(TcpSocket* sock){
      struct sockaddr_in addr;
      socklen_t len=sizeof(addr);
      int newfd=accept(_sockfd,(struct sockaddr*)&addr,&len);
      
      //int newfd=accept(_sockfd,NULL,NULL);
      if(newfd<0){
        perror("accept error!\n");
        return false;
      }
      sock->_sockfd=newfd;
      return true;
  }
  bool Recv(std::string* body){
      char tmp[1024]={0};
      int ret=recv(_sockfd,tmp,1024,0);
      if(ret<0){
           //EAGAIN 当前接收数据时，socket 接收缓冲区没有数据；若阻塞操作则一直等待，若非阻塞则立即报错返回
            //EINTR 当前接收数据时，被信号打断了
          //if(errno==EAGAIN || errno == EINTR){
          //   return true;
         // }
          perror("recv error!\n");
          return true;
      }else if(ret==0){
        printf("peer shutdown!\n");
        return false;
      }
      body->assign(tmp,ret);
      return true;
  }
  bool Send(const std::string& body){
     // int slen=0;        //若一次性无法发送数据 --- 采用循环发送
      //while(slen<body.size()){ 
       // int ret=send(_sockfd,&body[slen],body.size()-slen,0);
       // if(ret<0){
        //   if(errno==EAGAIN || errno == EINTR){
         //     continue;
          // }
          // perror("send error!\n");
          // return false;
       // }
       // slen+=ret;
     // }

      int ret=send(_sockfd,body.c_str(),body.size(),0);
      if(ret<0){
         //if(errno==EAGAIN || errno ==EINTR){
           //   return true;
        // }
         perror("send error");
         return true;
      }
      return true;
  }
  bool Close(){
    if(_sockfd > 0){
      close(_sockfd);
      _sockfd=-1;
    }
    return true;
  }
};

#endif
